#include <ncurses.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include "common.h"

struct list_item {
	gchar *text;
	int attr;
};

GSList *categories = NULL;
WINDOW *clistwin = NULL;

gint contact_list_width = 30;
int list_offset = 0, list_marked = 0;

void
draw_contact_list()
{
	GSList *categoryTmp;
	GPtrArray *array;
	struct list_item *item;
	int i, a;
	wchar_t *wchar_str;

	if (clistwin == NULL) {
		clistwin = newwin(get_max_y() - 2,
				  contact_list_width - 4,
				  1, get_max_x() - contact_list_width + 2);
	}
	wchar_str = g_malloc(sizeof(wchar_t) * contact_list_width + 1);

	if ((categoryTmp = categories) == NULL)
		return;

	/*
	 * Print the first few items (by calculating offset and shiet) 
	 */
	i = a = 0;
	do {
		array = (GPtrArray *) categoryTmp->data;
		if (i + array->len > list_offset) {
			a = list_offset - i;
			break;
		}
		i += array->len;
	} while ((categoryTmp = g_slist_next(categoryTmp)) != NULL);

	i = 0;
	while (categoryTmp != NULL && i < get_max_y() - 2) {
		array = (GPtrArray *) categoryTmp->data;
		for (; a < array->len; a++, i++) {
			item = g_ptr_array_index(array, a);
			g_assert(item != NULL);

			wchar_from_utf8(item->text, wchar_str,
					contact_list_width);
			wattron(clistwin, item->attr);
			mvwaddnwstr(clistwin, i, 0, wchar_str,
				    contact_list_width - 4);
			wattroff(clistwin, item->attr);
		}

		/*
		 * reset for next category 
		 */
		a = 0;

		categoryTmp = g_slist_next(categoryTmp);
	}

	g_free(wchar_str);

	wrefresh(clistwin);
}

void
destroy_contact_list()
{
	werase(clistwin);
	wrefresh(clistwin);
	delwin(clistwin);
	clistwin = NULL;
}

gint
sort_function(gconstpointer a, gconstpointer b)
{
	gchar *aNew, *bNew;
	gint r;

	if (a == b)
		return TRUE;

	if (!a || !b)
		return FALSE;

	aNew = g_utf8_casefold((gchar *) a, -1);
	bNew = g_utf8_casefold((gchar *) b, -1);

	r = g_utf8_collate(aNew, bNew);

	g_free(aNew);
	g_free(bNew);

	return r;
}

void
add_category(gchar * title)
{
	struct list_item *c;
	GPtrArray *array = NULL;

	c = (struct list_item *)g_malloc(sizeof(struct list_item));
	c->text = g_strdup(title);
	c->attr = A_BOLD;

	array = g_ptr_array_new();
	g_ptr_array_add(array, (gpointer) c);
	categories = g_slist_append(categories, array);
}

void
add_item(guint category_index, gchar * text, int attr)
{
	struct list_item *c;
	GPtrArray *array = NULL;

	c = (struct list_item *)g_malloc(sizeof(struct list_item));
	c->text = g_strdup(text);
	c->attr = attr;

	array = (GPtrArray *) g_slist_nth_data(categories, category_index);
	g_assert(array != NULL);
	g_ptr_array_add(array, (gpointer) c);
}

void
set_contact_list_width(int a)
{
	contact_list_width = a;
}

int
get_contact_list_width()
{
	return contact_list_width;
}
